﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Locadora.BLL.DAL;
using Locadora.TOB;
using System.Transactions;
using TagCloud;
using IMDBDLL;
using Google.GData.Client;
namespace Locadora.BLL
{
    public class DvdBLL
    {
        TB_DVD m_tb_dvd = null;
        private IMDbManager manag;
        private IMDbTitle tituloIMDB;
        private List<IMDbLink> listaTitulosIMDB;
        public delegate void functionCall(int type, object result);

        /// <summary>
        /// Delegate to call the errorHandler.
        /// </summary>
        /// <param name="exc">The Exception.</param>
        public delegate void errorCall(Exception exc);

        /// <summary>
        /// Delegate to call the progressUpdater.
        /// </summary>
        /// <param name="value">Value to add to the progress bar.</param>
        public delegate void progressCall(int value);

        /// <summary>
        /// Event of functionCall.
        /// </summary>
        private event functionCall formFunctionCaller;

        /// <summary>
        /// Event of errorCall.
        /// </summary>
        private event errorCall formErrorCaller;

        /// <summary>
        /// Event of progressCall.
        /// </summary>
        private event progressCall formProgressCaller;

        /// <summary>
        /// Boolean that tells if there was an error.
        /// </summary>
        private bool error = false;

        /// <summary>
        /// The api manager instance.
        /// </summary>

        public DvdBLL()
        {

        }
        public DvdBLL(TB_DVD tb)
        {
            m_tb_dvd = tb;
        }
        public static List<TB_DVD> Listar()
        {
            return DvdDAL.Listar();
        }
        public static Dictionary<string, int> GetClouds()
        {
            return DvdDAL.ListarTotalLocacoes();
        }
        public List<TB_DVD> ListarByCoUsuario(string coUsuario)
        {
            return DvdDAL.ListarByCoUsuario(coUsuario);
        }

        public static TB_DVD Listar(decimal? id)
        {
            return DvdDAL.Listar(id);
        }
        public static TB_DVD Listar(string nome)
        {
            return DvdDAL.Listar(nome);
        }        
        public void Update()
        {
            DvdDAL.Update(m_tb_dvd);
        }

        public void AlugarFilme(UsuarioTOB proprietario, UsuarioTOB solicitante)
        {
            List<TB_LOCACAO> listaTotal = LocacaoBLL.ListarLocadoByUsuario(solicitante.CO_USUARIO);

            if (listaTotal != null && listaTotal.Count >= 3)
            {
                throw new Exception("O máximo de DVDs que podem ser locados é de 3(três) DVD(s)");
            }

            using ( TransactionScope trans = new TransactionScope())
            {
                try
                {
                    //Atualiza flag
                    DvdDAL.UpdateFlagLocacao(m_tb_dvd);
                    //cadastrar a locaçao
                    TB_LOCACAO locacao = new TB_LOCACAO();
                    locacao.CO_DVD = m_tb_dvd.CO_SEQ_DVD;
                    locacao.CO_USUARIO = solicitante.CO_USUARIO;
                    locacao.DT_LOCACAO = DateTime.Now;
                    //locacao.DT_DEVOLUCAO = DateTime.Now.AddDays(5);
                    //locacao.ST_DEVOLVIDO = false;
                    LocacaoBLL locBll = new LocacaoBLL(locacao);
                    locBll.Inserir();
                    //commit
                    trans.Complete();
                    trans.Dispose();



                    StringBuilder sbMensagem = new StringBuilder();
                    
                    sbMensagem.Append("Prezado " +  proprietario.DS_NOME + ", ");

                    string filme = m_tb_dvd.DS_TITULO;
                   // string solicitante = Membership.GetUser(new Guid(locacao.CO_USUARIO));

                    sbMensagem.Append(string.Format("seu colega {0} está solicitando o filme {1}, entre no DVD Share e libere o emprestimo antes de emprestar o DVD",solicitante.DS_NOME,filme));
                    


                    EmailBLL email = new EmailBLL();

                    email.SpeedMail(solicitante.DS_EMAIL, proprietario.DS_EMAIL, "DVD Share - Solicitação!", sbMensagem.ToString());

                }
                catch (Exception)
                {
                    //rollback
                    trans.Dispose();
                    throw;
                }
            }
        }

        public void Inserir()
        {
            DvdDAL.Inserir(m_tb_dvd);
        }

        public void Devolver(string comentario, string coUsuario, decimal coLocacao)
        {
            using (TransactionScope trans = new TransactionScope())
            {
                try
                {
                    DvdDAL.Devolver(m_tb_dvd);
                    LocacaoBLL.Devolver(m_tb_dvd.CO_SEQ_DVD, coLocacao,coUsuario);
                    if (comentario.Trim() != "")
                    {
                        //cadastra comentario
                        TB_COMENTARIO comen = new TB_COMENTARIO();
                        comen.CO_DVD = m_tb_dvd.CO_SEQ_DVD;
                        comen.DS_COMENTARIO = comentario;
                        comen.DT_CADASTRO = DateTime.Now;
                        comen.CO_USUARIO = coUsuario;
                        ComentarioBLL bll = new ComentarioBLL(comen);
                        bll.Inserir();
                    }
                    trans.Complete();
                    trans.Dispose();
                }
                catch (Exception )
                {
                    trans.Dispose();
                    throw;
                }
            }
           
        }

        public static int GetTotalDvds()
        {
            return DvdDAL.GetTotalDvds();
        }

        public static List<TB_DVD> GetDvds(int start, int offset)
        {
            return DvdDAL.GetDvds(start, offset);
        }




        public void ReservarFilme(UsuarioTOB proprietario, UsuarioTOB solicitante)
        {
            List<TB_LOCACAO> listaTotal = LocacaoBLL.ListarReservaByUsuario(solicitante.CO_USUARIO);

            if (listaTotal != null && listaTotal.Count > 0)
            {
                throw new Exception("O máximo de DVD que podem ser reservado é de 1(um) DVD");
            }
            else if (listaTotal != null && listaTotal[0].CO_DVD == m_tb_dvd.CO_SEQ_DVD)
            {
                throw new Exception("Reserva já solicitada.");
            }
            using (TransactionScope trans = new TransactionScope())
            {
                try
                {
                    //cadastrar a locaçao
                    TB_LOCACAO locacao = new TB_LOCACAO();
                    locacao.CO_DVD = m_tb_dvd.CO_SEQ_DVD;
                    locacao.CO_USUARIO = solicitante.CO_USUARIO;
                    locacao.DT_LOCACAO = DateTime.Now;
                    locacao.ST_LOCACAO = (int)Locadora.TOB.Enumeracao.SituacaoLocacao.Reserva;
                    //locacao.DT_DEVOLUCAO = DateTime.Now.AddDays(5);
                    //locacao.ST_DEVOLVIDO = false;
                    LocacaoBLL locBll = new LocacaoBLL(locacao);
                    locBll.Inserir();
                    //commit
                    trans.Complete();
                    trans.Dispose();

                    StringBuilder sbMensagem = new StringBuilder();

                    sbMensagem.Append("Prezado " + proprietario.DS_NOME + ", ");

                    string filme = m_tb_dvd.DS_TITULO;
                    // string solicitante = Membership.GetUser(new Guid(locacao.CO_USUARIO));

                    sbMensagem.Append(string.Format("seu colega {0} está solicitando reserva do filme {1}. Logo que disponível, entre no DVD Share e libere o empréstimo antes de emprestar o DVD", solicitante.DS_NOME, filme));

                    EmailBLL email = new EmailBLL();

                    email.SpeedMail(solicitante.DS_EMAIL, proprietario.DS_EMAIL, "DVD Share - Solicitação!", sbMensagem.ToString());

                }
                catch (Exception)
                {
                    //rollback
                    trans.Dispose();
                    throw;
                }
            }

        }



        public IMDbTitle GetInfoFilmeIMDB(string urlFilme)
        {
            formFunctionCaller += new functionCall(processResult);
            formErrorCaller += new errorCall(errorHandler);
            formProgressCaller += new progressCall(progressUpdater);
            manag = new IMDbManager();
            manag.parentErrorCaller = formErrorCaller;
            manag.parentFunctionCaller = formFunctionCaller;
            manag.parentProgressUpdaterCaller = formProgressCaller;
            error = false; //Reset the error.

            bool[] fields = { true, true, true, true, true, true, true, true, true, true, true }; //Parses all the fields.
            
            int media = 0, sSeas = 0, eSeas = 0,  nActors = 5;

            nActors = -1;
            manag.Fields = fields;
            manag.Media = media;
            manag.SSeas = sSeas;
            manag.ESeas = eSeas;
            manag.NActors = nActors;

            manag.IMDbParse(urlFilme);
            return tituloIMDB;
        }
        public List<IMDbLink> GetListaFilmeIMDB(string titulo)
        {
            formFunctionCaller += new functionCall(processResult);
            formErrorCaller += new errorCall(errorHandler);
            formProgressCaller += new progressCall(progressUpdater);
            String text = titulo;
            if (text != "") // if there is text in the textBox.
            {

                //Starts the manager of the api.

                manag = new IMDbManager();
                manag.parentErrorCaller = formErrorCaller;
                manag.parentFunctionCaller = formFunctionCaller;
                manag.parentProgressUpdaterCaller = formProgressCaller;
                error = false; //Reset the error.
                //Read the options of the user.
                bool[] fields = { true, true, true, true, true, true, true, true, true, true, true }; //Parses all the fields.
                bool titleR = true;
                int media = 0, sSeas = 0, eSeas = 0, searchMode = 0, nActors = 5;
                
                if (!titleR) // If it's to search by ID
                    searchMode = 1;
               
                 nActors = -1;               

                //Call the api.
                manag.IMDbSearch(searchMode, text, media, nActors, sSeas, eSeas, fields);
            }
           
            return listaTitulosIMDB;
        }

        public void processResult(int type, object result)
        {
            if (!error) // if no errors occured
            {
                if (type == 0) // if we get a title
                {
                    tituloIMDB = (IMDbTitle)result;
                                   

                }
                else if (type == 1) // if we get a result list
                {
                    listaTitulosIMDB = (List<IMDbLink>)result;
                                                            
                }
            }
        }
        public void progressUpdater(int value)
        {
            //progressBar1.Value += value;
        }
        public void errorHandler(Exception exc)
        {
            error = true;
            //button1.Enabled = true;
            //Cursor = Cursors.Default;
            //progressBar1.Value = 0;
            //MessageBox.Show(exc.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #region youtube


        public string GetYouTubeVideo(string filme)
        {
            string url = "http://gdata.youtube.com/feeds/videos?q=" + filme;
            AtomFeed myFeed = GetFeed(url, 1, 15);
            return DisplayFeed(myFeed);
        }

        /// <summary>
        /// Create and returns and Google.GData.Client.AtomFee from url with the specific start and number of items
        /// </summary>
        /// <param name="url"></param>
        /// <param name="start"></param>
        /// <param name="number"></param>
        /// <returns></returns>
        private AtomFeed GetFeed(string url, int start, int number)
        {
            System.Diagnostics.Trace.Write("Conectando youtube at " + url);
            FeedQuery query = new FeedQuery("");
            Service service = new Service("youtube", "exampleCo");
            query.Uri = new Uri(url);
            query.StartIndex = start;
            query.NumberToRetrieve = number;

            AtomFeed myFeed = service.Query(query);
            return myFeed;
        }

        /// <summary>
        /// Renders feed in example aspx page
        /// </summary>
        /// <param name="myFeed"></param>
        private string DisplayFeed(AtomFeed myFeed)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (AtomEntry entry in myFeed.Entries)
            {
                #region render each
                sb.Append("<br /><b>Título:</b> ");
                sb.Append(entry.Title.Text);
                sb.Append("<br /><b>Categorias:</b> ");
                foreach (AtomCategory cat in entry.Categories)
                {
                    sb.Append(cat.Term);
                    sb.Append(",");
                }
                sb.Append(RenderVideoEmbedded(getIDSimple(entry.Id.AbsoluteUri)));
                sb.Append("<br /><b>Publicado em:</b> ");
                sb.Append(entry.Published);
                #endregion
            }
            return sb.ToString();
        }
        /// <summary>
        /// Converts URL ID to short one
        /// </summary>
        /// <param name="googleID"></param>
        /// <returns></returns>
        private string getIDSimple(string googleID)
        {
            int lastSlash = googleID.LastIndexOf("/");
            return googleID.Substring(lastSlash + 1);
        }
        private string RenderVideoEmbedded(string idSimple)
        {
            return string.Format("<div id=\"video{0}\"><object width=\"425\" height=\"355\"><param name=\"movie\" value=\"http://www.youtube.com/v/{0}&rel=1\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/{0}&rel=1\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"355\"></embed></object></div>", idSimple);
        }
        #endregion

    }

}
